package com.aistar.util;

import com.aistar.mapper.EmployeeMapper;
import com.aistar.model.entity.Employee;
import com.aistar.model.entity.Recruitment;
import com.aistar.service.user.IEmployeeInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

@Component
public class ItemUtil {

    public List<Integer> LikeRecruitment(List<Employee> employeeList,List<List<Integer>> recruitmentCount,Integer employeeId,List<Integer> recruitmentEmployee){
        //输出求职者数量
        Integer N=employeeList.size();
        //建立用户稀疏矩阵,用户相似度计算
        //通过存放0建立一个只有0的矩阵----长度N是根据用户比较
        Integer[][] employeeItem=new Integer[N][N];
        for (int i = 0; i <N ; i++) {
            for (int j = 0; j <N ; j++) {
                employeeItem[i][j]=0;
//                System.out.print(employeeItem[i][j]);
            }
//            System.out.println();
        }
        //(存储每个求职者投递的职位的次数)存储每个求职者收藏的不同职位总数
        Map<Integer,Integer> recruitmentList=new HashMap<>();
        //建立职位投递到用户的倒排表
        Map<Integer, Set<Integer>> itemsEmployeeLike=new HashMap<>();
        //辅助存储职位合集--代表所有收藏职位
        Set<Integer> items= new HashSet<>();
        //辅助存储每一个求职者id映射
        Map<Integer,Integer> employeeID=new HashMap<>();
        //辅助存储每一个id映射求职者
        Map<Integer,Integer> idEmployee=new HashMap<>();

        //依次处理N个求职者
        for (int i = 0; i <N ; i++) {
            //获取求职者
            Integer employee=employeeList.get(i).getId();
            //用户投递职位(暂时先获取职位数)
            recruitmentList.put(employee,recruitmentCount.get(i).size());
//            System.out.println("求职者"+employee+"职位数"+recruitmentCount.get(i).size());
//            用户ID与稀疏矩阵建立对应关系
            employeeID.put(employee,i);
            idEmployee.put(i,employee);
            //建立物品--用户倒排表
            for (int j = 0; j < recruitmentCount.get(i).size() ; j++) {
                Integer recruitment=recruitmentCount.get(i).get(j);
                //建立物品-用户倒排表(add方法为讲求职者加进物品集合内)
                if(items.contains(recruitment)){
                    itemsEmployeeLike.get(recruitment).add(employee);
                }else{
                    items.add(recruitment);
//                    System.out.println(items);
                    //创建物品--用户的倒排关系
                    itemsEmployeeLike.put(recruitment,new HashSet<Integer>());
                    itemsEmployeeLike.get(recruitment).add(employee);
                }
            }
        }
//        System.out.println("输出关系倒排表:="+itemsEmployeeLike.toString());

//        //计算相似度矩阵
        Set<Map.Entry<Integer, Set<Integer>>> entrySet = itemsEmployeeLike.entrySet();
        Iterator<Map.Entry<Integer, Set<Integer>>> iterator = entrySet.iterator();
        while (iterator.hasNext()){
            Set<Integer> commonEmployee=iterator.next().getValue();
            for (Integer integer : commonEmployee) {
                for (Integer integer1 : commonEmployee) {
                    if(integer==integer1){
                        continue;
                    }
                    //计算用户u与用户v都有正反馈的物品总数
                    employeeItem[employeeID.get(integer)][employeeID.get(integer1)]+=1;
//                    System.out.print(employeeItem[employeeID.get(integer)][employeeID.get(integer1)]);
                }
            }
//            System.out.println();
        }
        //计算用户之间的相似度【余弦相似性】
        Integer recommendEmployeeId= employeeID.get(employeeId);
        for (int i = 0; i < employeeItem.length; i++) {
            if(i!=recommendEmployeeId){
//                System.out.println(idEmployee.get(recommendEmployeeId)+"--"+idEmployee.get(i)+"相似度"+employeeItem[recommendEmployeeId][i]/Math.sqrt(recruitmentList.get(idEmployee.get(recommendEmployeeId))*recruitmentList.get(idEmployee.get(i))));
            }
        }
        //计算指定用户recommendUser的物品推荐度
//        System.out.println(items);
        Map<Integer,Double> itemRecommendDegree=new HashMap<>();
        for (Integer item : items) {//遍历职位集合
//            System.out.println(item);
            //得到购买该商品得用户得集合
            Set<Integer> employees=itemsEmployeeLike.get(item);
//            System.out.println(employees);
            //如果被推荐得用户没有购买当前物品,则进行推荐度计算
            if(!employees.contains(employeeId)){
                double RecommendDegree = 0.0;
                for (Integer employee : employees) {
                    //推荐度计算
                    RecommendDegree+=employeeItem[employeeID.get(employeeId)][employeeID.get(employee)]/Math.sqrt(recruitmentList.get(employeeId)*recruitmentList.get(employee));
                }
//                System.out.println(item);
                itemRecommendDegree.put(item,RecommendDegree);
            }
        }
//        System.out.println("推荐度\n"+itemRecommendDegree);
        //取最大得5个
        if(itemRecommendDegree.size()<9){
            List<Integer> list=itemRecommendDegree.entrySet().stream() .sorted((entry1, entry2) -> entry2.getValue().compareTo(entry1.getValue()))
                    .map(entry -> entry.getKey()).collect(Collectors.toList())
                    .subList(0, itemRecommendDegree.size());
            List<Integer> recruitment = new ArrayList<>();
            for (Integer integer : recruitmentEmployee) {
                if(!items.contains(integer)){
                    recruitment.add(integer);
                }
            }
//            List<Long> list1=topicViewDao.findIDOrderByDate();
            for(int i=0;i<recruitment.size();i++){
                if(list.size()==9)
                    break;
                if(list.contains(recruitment.get(i)))
                    continue;
                list.add(recruitment.get(i));
            }
//            System.out.println(list);
            return list;
        }else {
            List<Integer> list = itemRecommendDegree.entrySet().stream()
                    .sorted((entry1, entry2) -> entry2.getValue().compareTo(entry1.getValue()))
                    .map(entry -> entry.getKey()).collect(Collectors.toList())
                    .subList(0,9);
//            System.out.println(list);
            return list;
        }
    }
}
